﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Eventing.Reader;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DriveBeamEditor.Controls.General.Popup
{
    public partial class PopupDropDown : ToolStripDropDown
    {
        #region Fields

        private PopupContainer _popupContainer;

        private ToolStripControlHost _host;

        #endregion

        #region Properties

        /// <summary>Gets or sets the popup container control</summary>
        public PopupContainer PopupContainer
        {
            get { return _popupContainer; }
            set
            {
                if (_popupContainer == value) return;
                _popupContainer = value;
                OnPopupContainerChanged();
            }
        }

        #endregion

        #region CTORs

        public PopupDropDown()
        {
            InitializeComponent();
        }

        #endregion

        #region Methods

        private void OnPopupContainerChanged()
        {
            /* Dispose of current host */
            if (_host != null)
            {
                _host.Dispose();
                _host = null;
            }

            /* No container */
            Items.Clear();
            if (PopupContainer == null) return;

            /* Create host */
            _host = new ToolStripControlHost(PopupContainer)
            {
                AutoSize = false
            };

            /* Configure */
            Padding = Margin = _host.Padding = _host.Margin = Padding.Empty;
            PopupContainer.Location = Point.Empty;

            /* Mount host */
            Items.Add(_host);

            /* Container events */
            PopupContainer.Disposed += (sender, args) => _host.Dispose();
            PopupContainer.ClosePopup += (sender, args) => Close(ToolStripDropDownCloseReason.CloseCalled);
        }

        public void Show(Control control)
        {
            if (control == null)
                throw new ArgumentNullException("control");

            Show(control, control.ClientRectangle);
        }

        public void Show(Form f, Point p)
        {
            Show(f, new Rectangle(p, new Size(0, 0)));

        }

        private void Show(Control control, Rectangle area)
        {
            if (control == null)
                throw new ArgumentNullException("control");


            var location = control.PointToScreen(new Point(area.Left, area.Top + area.Height));
            var screen = Screen.FromControl(control).WorkingArea;

            if (location.X + Size.Width > (screen.Left + screen.Width))
                location.X = (screen.Left + screen.Width) - Size.Width;

            if (location.Y + Size.Height > (screen.Top + screen.Height))
                location.Y -= Size.Height + area.Height;

            location = control.PointToClient(location);

            Show(control, location, ToolStripDropDownDirection.BelowRight);
        }

        #endregion

        #region Events

        protected override bool ProcessDialogKey(Keys keyData)
        {
            return (keyData & Keys.Alt) != Keys.Alt && base.ProcessDialogKey(keyData);
        }

        protected override void OnOpening(CancelEventArgs e)
        {
            if (PopupContainer == null || PopupContainer.IsDisposed || PopupContainer.Disposing)
            {
                e.Cancel = true;
                return;
            }
            base.OnOpening(e);
        }

        protected override void OnOpened(EventArgs e)
        {
            PopupContainer.Focus();

            base.OnOpened(e);
        }

        #endregion
    }
}
